Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Init rntr #1

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open

Init rntr #1

wants to merge 12 commits into from

Conversation

jackpope
Copy link
Owner

@jackpope jackpope commented Jan 9, 2024

Summary:

Changelog:

Test Plan:

}

interface IFabricUIManagerMock extends FabricUIManager {
fireEvent(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] Consider naming dispatchEvent to match browser JS naming: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent

Afaik, fireEvent is Testing Library specific name.

module.exports = {
haste: {
defaultPlatform: 'ios',
platforms: ['android', 'ios', 'native'],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you plan to have API to specify which platform to render as (ios, android)?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a task to follow up with a way to control this

type ReactNode = {
children: Array<ReactNode>,
props: {...},
viewName: string,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the host component name?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of instanceHandle?
How memoizedProps compare to regular props?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

host component name

You can see in the snapshot output, its RCTView or RCTText in this example. I'll have to look back at this with some custom components and see what those will come in as.

memoizedProps

I can't remember at the moment. But I think some properties weren't available as props but were in memoizedProps when I was working on this. Will look into it

import {act} from 'react-test-renderer';
import ReactFabric from 'react-native/Libraries/Renderer/shims/ReactFabric';

type ReactNode = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to provide toJson() on React Node, so that users could do focussed snapshots on only a part of the element tree?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will give this a try as a follow up

}
}

function findBy(node: ReactNode, predicate: ReactNode => boolean): ?ReactNode {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to return all nodes matching predicate, not just the first one. RNTL queries always validate the number of matching elements in the tree vs expected number informed by query variant (getBy vs getAllBy vs queryBy),

},
};

type RootReactNode = $ReadOnlyArray<ReactNode>;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: in what cases root node can be an array of nodes?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here... this is a manual typing based on the outputs we were inspecting from Fabric. Can be improved or resused from official types probably.

}
const containerTag = Math.round(Math.random() * 1000000);
act(() => {
ReactFabric.render(element, containerTag, () => {}, true);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to configure renderer to mimic RN renderer behavior of throwing error on passing text children to non-Text elements?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it seems better if that comes for free as part of using RN/Fabric rather than re-implementing one-off errors in the test renderer (if possible). I'm not sure where that error is sourced from though. Do you know?

return buildRenderResult(root);
}

export function fireEvent(node: ReactNode, eventName: 'press') {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to expose simulating multi-event interactions, they should involve delays between events like touchstart and touchend, and hence be async.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one of the hackiest parts of this prototype and will be rewritten completely. Adding delays/async behavior makes sense to me!

import {act} from 'react-test-renderer';
import ReactFabric from 'react-native/Libraries/Renderer/shims/ReactFabric';

type ReactNode = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: is this type representing only host components or would it also represent composite components like ReactTestInstance did in RTR?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently its an incomplete (and maybe inaccurate) typing representing the nodes created by Fabric. We can likely find and import the real typing. Although it may be purposely opaque, having trouble remembering now. But for input, we probably want to use the real typing. For output maybe we create a custom object with a subset of attributes that are useful for testing cases.


type RootReactNode = $ReadOnlyArray<ReactNode>;

type RenderResult = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Render result should include the root view, it it used by RNTL in couple of ways:

  1. passing it to the users so they can easily make assertions on root element
  2. using as query start for our own implementation of tree traversal
  3. check for element being in given element tree using parent travels too the root

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out. Adding another follow up item!

Copy link
Owner Author

@jackpope jackpope left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to follow up with a simplified PR to get a base landed that we can iterate on

module.exports = {
haste: {
defaultPlatform: 'ios',
platforms: ['android', 'ios', 'native'],
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a task to follow up with a way to control this

import {act} from 'react-test-renderer';
import ReactFabric from 'react-native/Libraries/Renderer/shims/ReactFabric';

type ReactNode = {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will give this a try as a follow up

type ReactNode = {
children: Array<ReactNode>,
props: {...},
viewName: string,
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

host component name

You can see in the snapshot output, its RCTView or RCTText in this example. I'll have to look back at this with some custom components and see what those will come in as.

memoizedProps

I can't remember at the moment. But I think some properties weren't available as props but were in memoizedProps when I was working on this. Will look into it

import {act} from 'react-test-renderer';
import ReactFabric from 'react-native/Libraries/Renderer/shims/ReactFabric';

type ReactNode = {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently its an incomplete (and maybe inaccurate) typing representing the nodes created by Fabric. We can likely find and import the real typing. Although it may be purposely opaque, having trouble remembering now. But for input, we probably want to use the real typing. For output maybe we create a custom object with a subset of attributes that are useful for testing cases.

},
};

type RootReactNode = $ReadOnlyArray<ReactNode>;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here... this is a manual typing based on the outputs we were inspecting from Fabric. Can be improved or resused from official types probably.


type RootReactNode = $ReadOnlyArray<ReactNode>;

type RenderResult = {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out. Adding another follow up item!

}
const containerTag = Math.round(Math.random() * 1000000);
act(() => {
ReactFabric.render(element, containerTag, () => {}, true);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it seems better if that comes for free as part of using RN/Fabric rather than re-implementing one-off errors in the test renderer (if possible). I'm not sure where that error is sourced from though. Do you know?

return buildRenderResult(root);
}

export function fireEvent(node: ReactNode, eventName: 'press') {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one of the hackiest parts of this prototype and will be rewritten completely. Adding delays/async behavior makes sense to me!

@mdjastrzebski
Copy link

@jackpope makes sense. Ping me whenever you need any review or consultation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants